package com.jht.bletool.fragment;

import android.app.Activity;
import android.app.Application;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.hjq.toast.ToastUtils;
import com.hjq.xtoast.XToast;
import com.jht.bletool.APP;
import com.jht.bletool.R;
import com.jht.bletool.adapter.ExpandableLvBTAdapter;
import com.jht.bletool.characteristic.TranslateData;
import com.jht.bletool.config.AppConfig;
import com.jht.bletool.entity.DataLog;
import com.jht.bletool.ui.DataTransmissionActivity;
import com.jht.bletool.util.BaseUtils;
import com.jht.bletool.util.DateUtil;
import com.jht.bletool.util.SelectParseClass;
import com.orhanobut.dialogplus.DialogPlus;
import com.orhanobut.dialogplus.OnCancelListener;
import com.orhanobut.dialogplus.OnClickListener;
import com.orhanobut.dialogplus.ViewHolder;
import com.rengwuxian.materialedittext.MaterialEditText;
import com.wang.avi.AVLoadingIndicatorView;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import top.codestudy.uuid.DataTranslate;

import static com.jht.bletool.ui.UIKeyCode.UI_CLOSE_PROGRESS;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link BLEServiceFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class BLEServiceFragment extends Fragment implements ExpandableLvBTAdapter.Callback {
    private static final String TAG = "BLEServiceFragment";

    private volatile boolean isSettingDescriptor = false;
    private BluetoothDevice bluetoothDevice;
    private int count = 0;
    private ExpandableListView mElvAllServices;
    private LinearLayout mLlAviParent;
    private final Handler handler = new Handler() {

        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case UI_CLOSE_PROGRESS:
                    closeProgress();
                    break;
            }

        }
    };
    private AVLoadingIndicatorView mAvi;
    private BluetoothGatt bluetoothGatt;
    private LinearLayout mLlLvParent;
    private volatile List<BluetoothGattService> services;
    private volatile List<BluetoothGattCharacteristic> allCharacteristics;
    private volatile Map<String, List<BluetoothGattCharacteristic>> uuid_map_char;

    /**
     * <String,List<TranslateData> : String 参数代表的是特征的UUID的完整字符串值
     */
    private Map<String,List<TranslateData>> packageMap = new HashMap<>();
    private Map<String,List<MoreData>> dataMap = new HashMap<>();

    private class MoreData {
        public byte[] value;
        public MoreData(byte[] data){
            this.value = data;
        }

        public byte[] getValue() {
            return value;
        }

        public void setValue(byte[] value) {
            this.value = value;
        }
    }
    public void clearMap(){
        for(Map.Entry<String,List<TranslateData>> entry :packageMap.entrySet()){
            packageMap.put(entry.getKey(),null);
        }
    }
    public void clearMapByKey(String key){
        List<TranslateData> translateData = packageMap.get(key);
        if (translateData != null){
            packageMap.put(key,null);
        }
    }
    //针对fff4 响应的通知数据的解析
    private void displayData(byte[] rev_string)
    {
        String rev_str = "";
        byte batterylevel =0x00;
        byte rpm = 0x00;
        byte res = 0x00;
        try {
            batterylevel=rev_string[10];
            rpm=rev_string[11];
            res=rev_string[12];
        } catch(StringIndexOutOfBoundsException e){
            e.printStackTrace();
        }
        rev_str +=" battery level:";
        rev_str +=batterylevel & 0x00ff;//String.valueOf(batteryleve);
        rev_str +="\n rpm:";
        rev_str +=rpm & 0x00ff;
        rev_str +="\n resistance:";
        rev_str +=res & 0x00ff;

    }

    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.i(TAG, "onMtuChanged: BluetoothGatt.GATT_SUCCESS");
            }
            Log.i(TAG, "onMtuChanged: mtu ==> " + mtu);
        }

        @Override
        public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
            super.onPhyRead(gatt, txPhy, rxPhy, status);
            if (status == BluetoothGatt.GATT_SUCCESS)
                Log.d(TAG, "onPhyRead: txPhy ==> " + txPhy + " ; rxPhy ==> " + rxPhy);
        }


        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

            if (newState == BluetoothProfile.STATE_CONNECTED) {
                Log.i(TAG, "onConnectionStateChange: BluetoothProfile.STATE_CONNECTED");
                clearMap();
                Intent intent = new Intent();
                intent.setAction("send_log");
                DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "", "device has connected", Color.parseColor("#1E90FF"));
                intent.putExtra("ble_log", dataLog);
                getActivity().sendBroadcast(intent);
                gatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                Log.i(TAG, "onConnectionStateChange: BluetoothProfile.STATE_DISCONNECTED");
                Intent intent = new Intent();
                intent.setAction("send_log");
                DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "", "device has disconnected", Color.parseColor("#ff0033"));
                intent.putExtra("ble_log", dataLog);
                intent.putExtra("ble_close", true);
                getActivity().sendBroadcast(intent);
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                services = gatt.getServices();
                uuid_map_char = new HashMap<>();
                if (services != null) {
                    for (int i = 0; i < services.size(); i++) {
                        BluetoothGattService bluetoothGattService = services.get(i);
                        Log.d(TAG, "onServicesDiscovered: " + bluetoothGattService.getUuid().toString() + " ;  services size = " + services.size());
                        List<BluetoothGattCharacteristic> characteristics = bluetoothGattService.getCharacteristics();
                        uuid_map_char.put(bluetoothGattService.getUuid().toString(), characteristics);
                        if (characteristics != null) {
                            for (int i1 = 0; i1 < characteristics.size(); i1++) {
                                Log.i(TAG, "onServicesDiscovered: i1 ==> " + characteristics.get(i1).getUuid().toString());
                                if ("00002ad9-0000-1000-8000-00805f9b34fb".equals(characteristics.get(i1).getUuid().toString())) {
                                    BluetoothGattDescriptor descriptor = characteristics.get(i1).getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
                                    bluetoothGatt.setCharacteristicNotification(characteristics.get(i1), true);
                                    Log.i(TAG, "onServicesDiscovered:2ad9 特殊处理 descriptor != null ? " + (descriptor != null));
                                    if (descriptor != null) {
                                        descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                                        bluetoothGatt.writeDescriptor(descriptor);
                                    }
                                    isSettingDescriptor = true;
                                    break;
                                }
                            }
                        }
                    }
                    // 到此数据整合完毕
                    handler.sendEmptyMessage(UI_CLOSE_PROGRESS);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            initExpandListView(services, uuid_map_char);
                        }
                    });
                } else {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            ToastUtils.show(R.string.no_service);
                        }
                    });
                }


            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {

        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            Log.i(TAG, "onCharacteristicRead: status ==> " + status + " ; characteristic => " + characteristic.getUuid().toString());
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 1. 查询处理此特征 的解析类
                // 2. 发送广播到日志fragment中记录数据
                String substring = characteristic.getUuid().toString().substring(0, 9);
                //TranslateData translateDataInstance = SelectParseClass.getTranslateDataInstance(characteristic);
                Object obj = DataTranslate.uuidMap.get(characteristic.getUuid().toString().toLowerCase());
                Class<TranslateData> c  = (Class<TranslateData>) obj;
                Constructor<TranslateData> constructor = null;
                try {
                    constructor = c.getConstructor(BluetoothGattCharacteristic.class);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (Exception e){
                    e.printStackTrace();
                }
                TranslateData translateData = null;
                try {
                    translateData = constructor.newInstance(characteristic);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (java.lang.InstantiationException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (Exception e){
                    e.printStackTrace();
                }

                if (translateData == null) {
                    Log.w(TAG, "onCharacteristicChanged: translateDataInstance == null and characteristic ==> " + characteristic.getUuid().toString());
                    Intent intent = new Intent();
                    intent.setAction("send_log");
                    DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "not support this characteristic - " + characteristic.getUuid().toString().substring(4, 8), "", Color.parseColor("#00A2E8"));
                    intent.putExtra("ble_log", dataLog);
                    getActivity().sendBroadcast(intent);
                    return;
                }
                Intent intent = new Intent();
                intent.setAction("send_log");
                DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[" + substring + "]:read: ", translateData.convert2String() + "" + BaseUtils.getHexString(translateData.getData()), Color.parseColor("#00A2E8"));
                intent.putExtra("ble_log", dataLog);
                getActivity().sendBroadcast(intent);
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            Log.i(TAG, "onCharacteristicWrite: status ==> " + status + " ; characteristic => " + characteristic.getUuid().toString());
            Log.i(TAG, "onCharacteristicWrite: bluetoothGatt == gatt ? " + (bluetoothGatt == gatt));
            if (status == BluetoothGatt.GATT_SUCCESS) {
                String characterProperties = getCharacterProperties(characteristic.getProperties());
                if (characterProperties.contains("WRITE")) {
                    Log.i(TAG, "onCharacteristicWrite: WRITE ； and gatt == null? " + (gatt == null));
                    if (gatt != null) {
                        gatt.readCharacteristic(characteristic);
                        //为  Fitness Machine Control Point 单独设置 , 此步骤我已经移到 发现服务方法内部 ==》 onServicesDiscovered
                    }
                }
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            int properties = characteristic.getProperties();
            String characterProperties = getCharacterProperties(properties);
            String type = "";
            if (characterProperties.contains("INDICATE")) {
                type = "INDICATE";
            } else if (characterProperties.contains("NOTIFY")) {
                type = "NOTIFY";
            }
            //特殊处理fff3
            if ("0000fff4-0000-1000-8000-00805f9b34fb".equals(characteristic.getUuid().toString())) {
                //获取到的不是镜像信息
                byte[] extraStr=characteristic.getValue();
                Log.d(TAG, "onCharacteristicChanged: 0000fff4 ");
                if(extraStr != null){
                    if(extraStr.length<5){
                        Intent intent = new Intent();
                        intent.setAction("send_log");
                        DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[0000fff4]:" + type + ": ", "msg to short! \n" + "" + BaseUtils.getHexString(extraStr), Color.parseColor("#DC143C"));
                        intent.putExtra("ble_log", dataLog);
                        getActivity().sendBroadcast(intent);
                        return;
                    }
                    int j=0;
                    for(int i=1;i<extraStr.length;i++){
                        if(extraStr.length>19){
                            Log.i(TAG,"");
                        }

                        if((extraStr[i]==0x55&&extraStr.length>(i+1)&&extraStr[i+1]==(byte)0xAA)
                                || i+1==extraStr.length){
                            byte[] ba=null;
                            if(i+1==extraStr.length){
                                ba=new byte[extraStr.length-j];
                                System.arraycopy(extraStr,j,ba,0, extraStr.length-j);
                                j=extraStr.length;
                            } else {
                                ba=new byte[i-j];
                                System.arraycopy(extraStr,j,ba,0,i-j);
                                j=i;
                            }

                            //int msgId=extraStr[5];
                            if(ba.length>=13&&ba[5]==0x50) { //获取到了rpm,batteryLevel,resistance

                            } else if(ba.length>=11&&ba[10]==0x00){  //设置阻力值成功回信(回信包还有误的情况)
                                Intent intent = new Intent();
                                intent.setAction("send_log");
                                DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[0000fff4]:" + type + ": ", "set ADC success(package problem)! \n" + "" + BaseUtils.getHexString(extraStr), Color.parseColor("#00A2E8"));
                                intent.putExtra("ble_log", dataLog);
                                getActivity().sendBroadcast(intent);
                            }else if(ba.length>=12&&ba[10]==0x51&&ba[11]==0x00){  //设置阻力值成功回信
                                Intent intent = new Intent();
                                intent.setAction("send_log");
                                DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[0000fff4]:" + type + ": ", "阻力信息发送成功! \n" + "" + BaseUtils.getHexString(extraStr), Color.parseColor("#00A2E8"));
                                intent.putExtra("ble_log", dataLog);
                                getActivity().sendBroadcast(intent);
                            }
                        }
                    }
                }
                return;
            }
            String substring = characteristic.getUuid().toString().substring(0, 9);
            Object obj = DataTranslate.uuidMap.get(characteristic.getUuid().toString().toLowerCase());
            Class<TranslateData> c  = (Class<TranslateData>) obj;
            Constructor<TranslateData> constructor = null;
            try {
                constructor = c.getConstructor(BluetoothGattCharacteristic.class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            TranslateData translateData = null;
            try {
                translateData = constructor.newInstance(characteristic);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (java.lang.InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            //TranslateData translateDataInstance = SelectParseClass.getTranslateDataInstance(characteristic);
            // translateDataInstance == null表示不存在能够解析此特征的类
            if (translateData == null) {
                Log.w(TAG, "onCharacteristicChanged: translateDataInstance == null and characteristic ==> " + characteristic.getUuid().toString());
                Intent intent = new Intent();
                intent.setAction("send_log");
                DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "not support this characteristic- " + characteristic.getUuid().toString().substring(4, 8), "", Color.parseColor("#ff0000"));
                intent.putExtra("ble_log", dataLog);
                getActivity().sendBroadcast(intent);
                return;
            }
            // 特殊处理 FITNESS MACHINE CONTROL POINT 的返回响应，其实这里可以TranslateData实例中加入控制显示的方法，但是只有一个特征需要这么处理，所有没必要
            if ("00002ad9-0000-1000-8000-00805f9b34fb".equals(characteristic.getUuid().toString())) {
                Intent intent = new Intent();
                intent.setAction("send_log");
                DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[" + substring + "]:" + type + ": ", translateData.convert2String()+ "" + BaseUtils.getHexString(characteristic.getValue()), Color.parseColor("#00A2E8"));
                intent.putExtra("ble_log", dataLog);
                getActivity().sendBroadcast(intent);
                return;
            }
            //start 记录蓝牙数据
            List<MoreData> moreDataList = dataMap.get(characteristic.getUuid().toString());
            if (moreDataList == null){
                moreDataList = new ArrayList<>();
            }
            moreDataList.add(new MoreData(translateData.getData()));
            dataMap.put(characteristic.getUuid().toString(),moreDataList);
            //end 记录蓝牙数据
            if (translateData.hasMoreData()){
                Log.d(TAG, "onCharacteristicChanged: hasMoreData ==> " + characteristic.getUuid().toString());
                List<TranslateData> translateData1 = packageMap.get(characteristic.getUuid().toString());
                if (translateData1 == null){
                    translateData1 = new ArrayList<>();
                }
                translateData1.add(translateData);
                packageMap.put(characteristic.getUuid().toString(),translateData1);
            }else {
                /**
                 * 没有更多的数据时的处理步骤：
                 * 1.遍历packageMap是否已经包含了此类数据
                 * 2.如果包含则先整合之前的数据，并且清空链表的数据，再通过广播直接发送数据；如果不包含，则直接通过广播发送数据
                 */
                List<TranslateData> translateData1 = packageMap.get(characteristic.getUuid().toString());
                List<MoreData> moreDataListShow = dataMap.get(characteristic.getUuid().toString());
                if (translateData1 != null){
                    Log.d(TAG, "onCharacteristicChanged: 合并数据 ==> " + characteristic.getUuid().toString());
                    translateData1.add(translateData);
                    boolean isFirstData = true;
                    TranslateData temp = null;
                    boolean containInvalidData = false;
                    for(TranslateData translateData2 : translateData1){
                        if(translateData2.isInvalidData()){
                            containInvalidData = true;
                            break;
                        }
                        if (isFirstData){
                            temp = translateData2;
                            isFirstData = false;
                        }else {
                            temp.merge(translateData2);
                        }
                    }
                    StringBuilder sb = new StringBuilder();
                    for (int i=0;i < moreDataListShow.size();i++){
                        sb.append(i+": "+BaseUtils.getHexString(moreDataListShow.get(i).getValue()));
                        sb.append(";\n");
                    }
                    packageMap.put(characteristic.getUuid().toString(),null);
                    dataMap.put(characteristic.getUuid().toString(),null);
                    if (temp == null){ //虽然，我觉得不可能为null，但是还补充下吧
                        return;
                    }
                    if(containInvalidData){
                        //包含非法数据
                        Intent intent = new Intent();
                        intent.setAction("send_log");
                        DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[" + substring + "]:" + type + ": ", "Invalid Data: \n"+ sb.toString(), Color.parseColor("#C80000"));
                        intent.putExtra("ble_log", dataLog);
                        getActivity().sendBroadcast(intent);
                    }else{
                        Intent intent = new Intent();
                        intent.setAction("send_log");
                        DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[" + substring + "]:" + type + ": ", temp.convert2String() + ""+ sb.toString(), Color.parseColor("#307A4B"));
                        intent.putExtra("ble_log", dataLog);
                        getActivity().sendBroadcast(intent);
                    }

                }else {
                    String hex_value = BaseUtils.getHexString(moreDataListShow.get(0).getValue())+"";
                    dataMap.put(characteristic.getUuid().toString(),null);
                    Log.d(TAG, "onCharacteristicChanged: 非合并数据 ==> " + characteristic.getUuid().toString());
                    if(translateData.isInvalidData()){
                        //非法数据
                        Intent intent = new Intent();
                        intent.setAction("send_log");
                        DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[" + substring + "]:" + type + ": ",  "Invalid Data: \n"+hex_value, Color.parseColor("#C80000"));
                        intent.putExtra("ble_log", dataLog);
                        getActivity().sendBroadcast(intent);
                    }else{
                        Intent intent = new Intent();
                        intent.setAction("send_log");
                        DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), "[" + substring + "]:" + type + ": ", translateData.convert2String()+""+hex_value, Color.parseColor("#307A4B"));
                        intent.putExtra("ble_log", dataLog);
                        getActivity().sendBroadcast(intent);
                    }

                }

            }

        }
    };
    private Button mBtnMtu;
    private XToast show;

    public BLEServiceFragment(BluetoothDevice ble_device) {
        bluetoothDevice = ble_device;
    }

    public static BLEServiceFragment newInstance(BluetoothDevice ble_device) {
        BLEServiceFragment fragment = new BLEServiceFragment(ble_device);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final Intent intent = new Intent();
        intent.setAction("send_log");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_all_services, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        mElvAllServices = view.findViewById(R.id.elv_all_services);
        mLlAviParent = view.findViewById(R.id.ll_avi_parent);
        mAvi = view.findViewById(R.id.avi);
        mLlLvParent = view.findViewById(R.id.ll_lv_parent);
        mBtnMtu = view.findViewById(R.id.btn_mtu);
        mBtnMtu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                DialogPlus dialog = DialogPlus.newDialog(getActivity())
//                        .setContentHolder(new ViewHolder(R.layout.dialog_view_set_mtu_data))
//                        .setOnClickListener(new OnClickListener() {
//                            @Override
//                            public void onClick(DialogPlus dialog, View view) {
//                                if (view.getId() == R.id.btn_send_mtu) {
//                                    MaterialEditText mEdTextCommandMtu = dialog.getHolderView().findViewById(R.id.ed_text_command_mtu);
//                                    switch (view.getId()) {
//                                        case R.id.btn_send_mtu:
//                                            String mtu = mEdTextCommandMtu.getText().toString();
//                                            if (bluetoothGatt == null) {
//                                                Log.e(TAG, "btn_send_mtu: bluetoothGatt == null");
//                                                return;
//                                            }
//                                            try {
//                                                bluetoothGatt.requestMtu(Integer.parseInt(mtu));
//                                            } catch (NumberFormatException e) {
//                                                ToastUtils.show("输入的MTU值不是一个正确整数！");
//                                            }
//                                            break;
//                                    }
//                                    dialog.dismiss();
//                                }
//                            }
//                        })
//                        .setCancelable(true)
//                        .create();
//                dialog.show();
                initControlInfoDialog();
            }
        });

        bluetoothGatt = bluetoothDevice.connectGatt(APP.getAppContext(), false, mGattCallback);


    }

    private void closeProgress() {
        mLlAviParent.setVisibility(View.GONE);
    }

    private ExpandableLvBTAdapter expandableLvBTAdapter = null;
    private List<BluetoothGattCharacteristic> characteristicsAllChild = new ArrayList<>();

    private void initExpandListView(List<BluetoothGattService> services, Map<String, List<BluetoothGattCharacteristic>> uuid_map_char) {
        expandableLvBTAdapter = new ExpandableLvBTAdapter(APP.getAppContext(), handler, services, uuid_map_char);
        for(BluetoothGattService bluetoothGattService: services){
            List<BluetoothGattCharacteristic> characteristics = bluetoothGattService.getCharacteristics();
            characteristicsAllChild.addAll(characteristics);
        }
        expandableLvBTAdapter.setCallback(this);
        mElvAllServices.setAdapter(expandableLvBTAdapter);

        mLlLvParent.setVisibility(View.VISIBLE);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");

        if (bluetoothGatt != null) {
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            bluetoothGatt = null;
        }
    }

    @Override
    public void read(BluetoothGattCharacteristic characteristic) {
        if (bluetoothGatt != null) {
            bluetoothGatt.readCharacteristic(characteristic);
        }
    }

    @Override
    public void write(final BluetoothGattCharacteristic characteristic) {
        //1.显示 输入数据 的弹框
        //2. 发送 数据
        //3. gatt回调中 接受响应
        DialogPlus dialog = DialogPlus.newDialog(getActivity())
                .setContentHolder(new ViewHolder(R.layout.dialog_view_send_data))
                .setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(DialogPlus dialog, View view) {
                        if (view.getId() == R.id.btn_send) {
                            MaterialEditText ed_text_command = (MaterialEditText) dialog.getHolderView().findViewById(R.id.ed_text_command);
                            MaterialEditText ed_text_param = (MaterialEditText) dialog.getHolderView().findViewById(R.id.ed_text_param);
                            switch (view.getId()) {
                                case R.id.btn_send:
                                    if (!isSettingDescriptor) {
                                        //在服务发现时，就对ftms control point 开启indicate，这里的标志位，表示是否开启成功；
                                        ToastUtils.show("请稍后等待一会儿再试！");
                                        break;
                                    }
                                    String strOperation = ed_text_command.getText().toString();
                                    String strParameter = ed_text_param.getText().toString();
                                    Log.i(TAG, "onClick: command ==> " + strOperation + " ; param ==> " + strParameter);


                                    int operation, pram;
                                    boolean havaParams = false;
                                    try {
                                        operation = Integer.parseInt(strOperation, 16);
                                        if (!"".equals(strParameter)) {
                                            havaParams = true;
                                            //特殊处理 ~~ ^~^ ~~
                                            if("0000fff3-0000-1000-8000-00805f9b34fb".equals(characteristic.getUuid().toString())){
                                                sendData(characteristic, havaParams, operation, strParameter);
                                                hideKeyboard(getActivity());
                                                dialog.dismiss();
                                                return;
                                            }

                                            if(strParameter.contains(",")){
                                                String[] split = strParameter.split(",");
                                                for(String num:split){
                                                    //异常判断
                                                    Integer.parseInt(num, 16);
                                                }
                                            }else {
                                                //异常判断
                                                 Integer.parseInt(strParameter, 16);
                                            }
                                        } else {

                                        }
                                    } catch (NumberFormatException ex) {
                                        Toast.makeText(APP.getAppContext(), "输入的参数必须是十进制整数", Toast.LENGTH_SHORT).show();
                                        ex.printStackTrace();
                                        return;
                                    }
                                    sendData(characteristic, havaParams, operation, strParameter);
                                    hideKeyboard(getActivity());
                                    break;
                            }
                            dialog.dismiss();
                        }

                        if (view.getId() == R.id.btn_record) {
                            MaterialEditText ed_text_command = (MaterialEditText) dialog.getHolderView().findViewById(R.id.ed_text_command);
                            MaterialEditText ed_text_param = (MaterialEditText) dialog.getHolderView().findViewById(R.id.ed_text_param);
                            Log.e(TAG, "onClick:btn_record======= ");
                            if (!isSettingDescriptor) {
                                //在服务发现时，就对ftms control point 开启indicate，这里的标志位，表示是否开启成功；
                                ToastUtils.show("请稍后等待一会儿再试！");
                                dialog.dismiss();
                                return;
                            }
                            /**
                             * 1.校验数据
                             * 2.如果数据合法，记录对应特征的数据到SharedPreferences，否则提示；
                             */
                            //第一步
                            String strOperation = ed_text_command.getText().toString();
                            String strParameter = ed_text_param.getText().toString();
                            Log.i(TAG, "btn_record onClick: command ==> " + strOperation + " ; param ==> " + strParameter);
                            int operation, pram;
                            boolean havaParams = false;
                            try {
                                operation = Integer.parseInt(strOperation, 16);
                                if (!"".equals(strParameter)) {
                                    havaParams = true;

                                    if(strParameter.contains(",")){
                                        String[] split = strParameter.split(",");
                                        for(String num:split){
                                            //异常判断
                                            Integer.parseInt(num, 16);
                                        }
                                    }else {
                                        //异常判断
                                        Integer.parseInt(strParameter, 16);
                                    }
                                } else {

                                }
                            } catch (NumberFormatException ex) {
                                Toast.makeText(APP.getAppContext(), "输入的参数必须是十进制整数", Toast.LENGTH_SHORT).show();
                                ex.printStackTrace();
                                return;
                            }
                            hideKeyboard(getActivity());
                            //第二步
                            SharedPreferences record_data = APP.getAppContext().getSharedPreferences(AppConfig.record_data, Context.MODE_PRIVATE);
                            SharedPreferences.Editor edit = record_data.edit();
                            Map<String, ?> all = record_data.getAll();
                            for(Map.Entry<String, ?> entry:all.entrySet()){
                                Log.e(TAG, "onClick: key=> " + entry.getKey()+"|| value ==>" + entry.getValue());
                            }
                            if(record_data.contains(characteristic.getUuid().toString().substring(4,8))){
                                Log.e(TAG, "onClick: SharedPreferences  data存在！");
                                String historyData = record_data.getString(characteristic.getUuid().toString().substring(4,8),"");
                                edit.putString(characteristic.getUuid().toString().substring(4,8),historyData+";"+ strOperation+"@"+strParameter);
                            }else{
                                Log.e(TAG, "onClick: SharedPreferences  data不存在！");
                                edit.putString(characteristic.getUuid().toString().substring(4,8),strOperation+"@"+strParameter);
                            }
                            edit.apply();
                            dialog.dismiss();
                        }
                    }
                })
                .setOnCancelListener(new OnCancelListener() {
                    @Override
                    public void onCancel(DialogPlus dialog) {
                        hideKeyboard(getActivity());
                    }
                })
                .setCancelable(true)
                .create();
        dialog.show();

    }

    //隐藏软键盘
    public void hideKeyboard(Activity activity) {
        try {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
        } catch (NullPointerException e) {
            Log.e("hideKeyboard", e.toString());
        }
    }

    @Override
    public void CharacteristicNotify(BluetoothGattCharacteristic characteristic) {
        if (bluetoothGatt != null) {
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));

            bluetoothGatt.setCharacteristicNotification(characteristic, true);
            Log.i(TAG, "setCharacteristicNotification: descriptor != null ? " + (descriptor != null));


            if (descriptor != null) {
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                bluetoothGatt.writeDescriptor(descriptor);
            }
        }
    }

    @Override
    public void CharacteristicIndicate(BluetoothGattCharacteristic characteristic) {
        if (bluetoothGatt != null) {
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));

            bluetoothGatt.setCharacteristicNotification(characteristic, true);
            Log.i(TAG, "setCharacteristicNotification: descriptor != null ? " + (descriptor != null));


            if (descriptor != null) {
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                bluetoothGatt.writeDescriptor(descriptor);
            }
        }
    }

    @Override
    public void closeNotify(BluetoothGattCharacteristic characteristic) {
        if (bluetoothGatt != null) {
            clearMapByKey(characteristic.getUuid().toString());
            bluetoothGatt.setCharacteristicNotification(characteristic, false);
        }
    }

    public String getCharacterProperties(int properties) {
        String propertiesStr = "";
        if ((properties & BluetoothGattCharacteristic.PROPERTY_BROADCAST) == BluetoothGattCharacteristic.PROPERTY_BROADCAST) {
            propertiesStr += "BROADCAST,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_READ) == BluetoothGattCharacteristic.PROPERTY_READ) {
            propertiesStr += "READ,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) {
            propertiesStr += "W_N_RESP,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) == BluetoothGattCharacteristic.PROPERTY_WRITE) {
            propertiesStr += "WRITE,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == BluetoothGattCharacteristic.PROPERTY_NOTIFY) {
            propertiesStr += "NOTIFY,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == BluetoothGattCharacteristic.PROPERTY_INDICATE) {
            propertiesStr += "INDICATE,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) == BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) {
            propertiesStr += "SIGNED_WRITE,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) == BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) {
            propertiesStr += "EXTENDED_PROPS,";
        }
        return propertiesStr;
    }


    public void sendGroupRecordData(String groupUUID,List<String> data){

    }

    public void sendChildRecordData(String groupUUID,String data){
        for(BluetoothGattCharacteristic characteristic:characteristicsAllChild){
            if(characteristic.getUuid().toString().substring(4,8).equals(groupUUID)){
                String[] split = data.split("@");
                if (split.length == 1){
                    int parseInt = Integer.parseInt(split[0], 16);
                    sendData(characteristic,false,parseInt,"");
                    recordLog("command:"+split[0]+"\n data: null");
                }else if(split.length == 2){
                    int parseInt = Integer.parseInt(split[0], 16);
                    sendData(characteristic,true,parseInt,split[1]);
                    recordLog("command:"+split[0]+"\n data: "+split[1]+"");
                }
                return;
            }
        }
        Toast.makeText(APP.getAppContext(),"Can‘t send command!",Toast.LENGTH_SHORT).show();
    }


    public void sendData(BluetoothGattCharacteristic currentWriteCharacteristicFromStrUUID, boolean hasParam, int mCurrentOperation, String mCurrentParams) {
        if (!"00002ad9-0000-1000-8000-00805f9b34fb".equals(currentWriteCharacteristicFromStrUUID.getUuid().toString()) && !"0000fff3-0000-1000-8000-00805f9b34fb".equals(currentWriteCharacteristicFromStrUUID.getUuid().toString())) {
            ToastUtils.show("不支持此特征的数据写入！");
            return;
        }
        if (bluetoothGatt == null) {
            Log.e(TAG, "sendData: bluetoothGatt == null");
            return;
        }

        if("0000fff3-0000-1000-8000-00805f9b34fb".equals(currentWriteCharacteristicFromStrUUID.getUuid().toString())){
            if(hasParam){
                switch(mCurrentOperation){
                    case 1://修改名字
                        String name = mCurrentParams;
                        int length=name.getBytes().length;
                        byte[] msg=new byte[length+3];
                        msg[0]=0x0A;
                        msg[1]=(byte)length;
                        int i=0;
                        for(;i<length;i++){
                            try {
                                msg[2+i]=name.getBytes("UTF-8")[i];
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                                msg[2+i]=name.getBytes()[i];
                                ToastUtils.show("change BT name : getByte(UTF-8) error");
                            }
                        }
                        msg[2+i]=(byte)0xA0;
                        currentWriteCharacteristicFromStrUUID.setValue(msg);
                        bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
                       return;
                    case 2://设置阻力
                        Integer option = 0;
                        try{
                            option = Integer.valueOf(mCurrentParams);
                            if(option <=0 || option > 12){
                                ToastUtils.show("CurrentParams：must  >= 1 and <=12 !");
                                return ;
                            }
                            byte[] msg2=new byte[]{0x55,(byte)0xAA,0,0,0x02,0x51,0x01,0x00,0x00,0x00,option.byteValue()};
                            byte[] crc= BaseUtils.crc_16_CCITT_False(new byte[]{option.byteValue()});
                            if(crc.length==2) {
                                msg2[8] =crc[0];
                                msg2[9] =crc[1];
                            } else {
                                ToastUtils.show("crc calculate error");
                                return ;
                            }
                            currentWriteCharacteristicFromStrUUID.setValue(msg2);
                            bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
                        }catch (NumberFormatException e){
                            ToastUtils.show("Operation：must Integer!");
                            return;
                        }
                       return;
                    default:
                        ToastUtils.show("Operation：must 1 or 2 !");
                        return;
                }
            }
        }

        byte[] data = null;
        if (hasParam) {
            Log.i(TAG, "writeCharacteristic: 0x08");
            data = new byte[initDataLength(mCurrentOperation)];
        }
        if (data != null) {
            if (mCurrentOperation == 0x0c) {
                data = new byte[4];
                data[0] = (byte) mCurrentOperation;
                int data16 = Integer.parseInt(mCurrentParams, 10);
                String unsignedString = BaseUtils.toHex(data16, 16);
                int num = 6 - unsignedString.length();
                for (int i = 0; i < num; i++) {
                    unsignedString = "0" + unsignedString;
                }
                data[3] = (byte) Integer.parseInt(unsignedString.substring(0, 2), 16);
                data[2] = (byte) Integer.parseInt(unsignedString.substring(2, 4), 16);
                data[1] = (byte) Integer.parseInt(unsignedString.substring(4), 16);
                currentWriteCharacteristicFromStrUUID.setValue(data);
                bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
                return;
            }
            //Set Targeted Time in Two Heart Rate Zones
            if (mCurrentOperation == 0x0E) {
                data = new byte[5];
                data[0] = (byte) mCurrentOperation;
                if (!mCurrentParams.contains(",")){
                    ToastUtils.show("输入的参数格式不正确，需要包含 ，作为分隔符！");
                    return;
                }
                String[] datas = mCurrentParams.split(",");

                int data16 = Integer.parseInt(datas[0], 10);
                String unsignedString = BaseUtils.toHex(data16, 16);

                int data16_2 = Integer.parseInt(datas[1], 10);
                String unsignedString_2 = BaseUtils.toHex(data16_2, 16);

                int num = 4 - unsignedString.length();
                for (int i = 0; i < num; i++) {
                    unsignedString = "0" + unsignedString;
                }
                data[2] = (byte) Integer.parseInt(unsignedString.substring(0, 2), 16);
                data[1] = (byte) Integer.parseInt(unsignedString.substring(2), 16);

                int num2 = 4 - unsignedString_2.length();
                for (int i = 0; i < num2; i++) {
                    unsignedString_2 = "0" + unsignedString_2;
                }
                data[4] = (byte) Integer.parseInt(unsignedString_2.substring(0, 2), 16);
                data[3] = (byte) Integer.parseInt(unsignedString_2.substring(2), 16);

                currentWriteCharacteristicFromStrUUID.setValue(data);
                bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
                return;
            }
            //Set Targeted Time in Three Heart Rate Zones
            if (mCurrentOperation == 0x0F) {
                data = new byte[7];
                data[0] = (byte) mCurrentOperation;
                if (!mCurrentParams.contains(",")){
                    ToastUtils.show("输入的参数格式不正确，需要包含 ，作为分隔符！");
                    return;
                }
                String[] datas = mCurrentParams.split(",");

                int data16 = Integer.parseInt(datas[0], 10);
                String unsignedString = BaseUtils.toHex(data16, 16);

                int data16_2 = Integer.parseInt(datas[1], 10);
                String unsignedString_2 = BaseUtils.toHex(data16_2, 16);

                int data16_3 = Integer.parseInt(datas[2], 10);
                String unsignedString_3 = BaseUtils.toHex(data16_3, 16);

                int num = 4 - unsignedString.length();
                for (int i = 0; i < num; i++) {
                    unsignedString = "0" + unsignedString;
                }
                data[2] = (byte) Integer.parseInt(unsignedString.substring(0, 2), 16);
                data[1] = (byte) Integer.parseInt(unsignedString.substring(2), 16);

                int num2 = 4 - unsignedString_2.length();
                for (int i = 0; i < num2; i++) {
                    unsignedString_2 = "0" + unsignedString_2;
                }
                data[4] = (byte) Integer.parseInt(unsignedString_2.substring(0, 2), 16);
                data[3] = (byte) Integer.parseInt(unsignedString_2.substring(2), 16);

                int num3 = 4 - unsignedString_3.length();
                for (int i = 0; i < num3; i++) {
                    unsignedString_3 = "0" + unsignedString_3;
                }
                data[6] = (byte) Integer.parseInt(unsignedString_3.substring(0, 2), 16);
                data[5] = (byte) Integer.parseInt(unsignedString_3.substring(2), 16);

                currentWriteCharacteristicFromStrUUID.setValue(data);
                bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
                return;
            }
            //Set Targeted Time in Five Heart Rate Zones
            if (mCurrentOperation == 0x10) {
                data = new byte[11];
                data[0] = (byte) mCurrentOperation;
                if (!mCurrentParams.contains(",")){
                    ToastUtils.show("输入的参数格式不正确，需要包含 ，作为分隔符！");
                    return;
                }
                String[] datas = mCurrentParams.split(",");

                int data16 = Integer.parseInt(datas[0], 10);
                String unsignedString = BaseUtils.toHex(data16, 16);

                int data16_2 = Integer.parseInt(datas[1], 10);
                String unsignedString_2 = BaseUtils.toHex(data16_2, 16);

                int data16_3 = Integer.parseInt(datas[2], 10);
                String unsignedString_3 = BaseUtils.toHex(data16_3, 16);
                int data16_4 = Integer.parseInt(datas[3], 10);
                String unsignedString_4 = BaseUtils.toHex(data16_4, 16);

                int data16_5 = Integer.parseInt(datas[4], 10);
                String unsignedString_5 = BaseUtils.toHex(data16_5, 16);

                int num = 4 - unsignedString.length();
                for (int i = 0; i < num; i++) {
                    unsignedString = "0" + unsignedString;
                }
                data[2] = (byte) Integer.parseInt(unsignedString.substring(0, 2), 16);
                data[1] = (byte) Integer.parseInt(unsignedString.substring(2), 16);

                int num2 = 4 - unsignedString_2.length();
                for (int i = 0; i < num2; i++) {
                    unsignedString_2 = "0" + unsignedString_2;
                }
                data[4] = (byte) Integer.parseInt(unsignedString_2.substring(0, 2), 16);
                data[3] = (byte) Integer.parseInt(unsignedString_2.substring(2), 16);

                int num3 = 4 - unsignedString_3.length();
                for (int i = 0; i < num3; i++) {
                    unsignedString_3 = "0" + unsignedString_3;
                }
                data[6] = (byte) Integer.parseInt(unsignedString_3.substring(0, 2), 16);
                data[5] = (byte) Integer.parseInt(unsignedString_3.substring(2), 16);

                int num4 = 4 - unsignedString_4.length();
                for (int i = 0; i < num4; i++) {
                    unsignedString_4 = "0" + unsignedString_4;
                }
                data[8] = (byte) Integer.parseInt(unsignedString_4.substring(0, 2), 16);
                data[7] = (byte) Integer.parseInt(unsignedString_4.substring(2), 16);

                int num5 = 4 - unsignedString_5.length();
                for (int i = 0; i < num5; i++) {
                    unsignedString_5 = "0" + unsignedString_5;
                }
                data[10] = (byte) Integer.parseInt(unsignedString_5.substring(0, 2), 16);
                data[9] = (byte) Integer.parseInt(unsignedString_5.substring(2), 16);
                Log.i(TAG, "sendData: 发送的数据为 ==> " + AppConfig.getHexString(data));
                currentWriteCharacteristicFromStrUUID.setValue(data);
                bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
                return;
            }
            //Set Indoor Bike Simulation Parameters Procedure
            if (mCurrentOperation == 0x11) {
                data = new byte[7];
                data[0] = (byte) mCurrentOperation;
                if (!mCurrentParams.contains(",")){
                    ToastUtils.show("输入的参数格式不正确，需要包含 ，作为分隔符！");
                    return;
                }
                String[] datas = mCurrentParams.split(",");

                int data16 = Integer.parseInt(datas[0], 10);
                String unsignedString = BaseUtils.toHex(data16, 16);

                int data16_2 = Integer.parseInt(datas[1], 10);
                String unsignedString_2 = BaseUtils.toHex(data16_2, 16);

                int data16_3 = Integer.parseInt(datas[2], 10);
                String unsignedString_3 = BaseUtils.toHex(data16_3, 16);
                int data16_4 = Integer.parseInt(datas[3], 10);
                String unsignedString_4 = BaseUtils.toHex(data16_4, 16);

                int num = 4 - unsignedString.length();
                for (int i = 0; i < num; i++) {
                    unsignedString = "0" + unsignedString;
                }
                data[2] = (byte) Integer.parseInt(unsignedString.substring(0, 2), 16);
                data[1] = (byte) Integer.parseInt(unsignedString.substring(2), 16);

                int num2 = 4 - unsignedString_2.length();
                for (int i = 0; i < num2; i++) {
                    unsignedString_2 = "0" + unsignedString_2;
                }
                data[4] = (byte) Integer.parseInt(unsignedString_2.substring(0, 2), 16);
                data[3] = (byte) Integer.parseInt(unsignedString_2.substring(2), 16);

                data[5] = (byte)Integer.parseInt(unsignedString_3,16);
                data[6] = (byte)Integer.parseInt(unsignedString_4,16);
                currentWriteCharacteristicFromStrUUID.setValue(data);
                bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
                return;
            }

            if (data.length == 2) {
                data[0] = (byte) mCurrentOperation;
                data[1] = (byte) Integer.parseInt(mCurrentParams, 10);
                currentWriteCharacteristicFromStrUUID.setValue(data);
            } else if (data.length == 3) {
                data[0] = (byte) mCurrentOperation;
                int data16 = Integer.parseInt(mCurrentParams, 10);
                String unsignedString = BaseUtils.toHex(data16, 16);
                if (unsignedString.length() <= 2) {
                    data[2] = 0;
                    data[1] = (byte) Integer.parseInt(unsignedString, 16);

                }
                if (unsignedString.length() == 3) {
                    data[2] = (byte) Integer.parseInt(unsignedString.substring(0, 1), 16);
                    data[1] = (byte) Integer.parseInt(unsignedString.substring(1), 16);
                }
                if (unsignedString.length() == 4) {
                    data[2] = (byte) Integer.parseInt(unsignedString.substring(0, 2), 16);
                    data[1] = (byte) Integer.parseInt(unsignedString.substring(2), 16);
                }
                Log.i(TAG, "onDescriptorWrite: unsignedString.length() < 2 || data[1] = " + Integer.toHexString(data[1]&0xff) + "; " + Integer.toHexString(data[2]&0xff) );
                currentWriteCharacteristicFromStrUUID.setValue(data);
            } else {
                byte[] bytes = new byte[1];
                bytes[0] = (byte) mCurrentOperation;
                currentWriteCharacteristicFromStrUUID.setValue(bytes);
            }
        } else {
            Log.i(TAG, "sendData: 00 没有参数");
            byte[] bytes = new byte[1];
            bytes[0] = (byte) mCurrentOperation;
            currentWriteCharacteristicFromStrUUID.setValue(bytes);
//            currentWriteCharacteristicFromStrUUID.setValue(mCurrentOperation, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
        }
        bluetoothGatt.writeCharacteristic(currentWriteCharacteristicFromStrUUID);
    }

    private int initDataLength(int currentOperation) {
        switch (currentOperation) {
            case 0x00:
            case 0x01:
                return 0;
            case 0x02:
            case 0x03:
                return 3;
            case 0x04:
                return 2;
            case 0x05:
                return 3;
            case 0x06:
                return 2;
            case 0x07:
                return 0;
            case 0x08:
                return 2;
            case 0x09:
                return 3;
            case 0x0A:
                return 3;
            case 0x0B:
                return 3;
            case 0x0C:
                return 4;
            case 0x0D:
                return 3;
            case 0x0E:
                return 5;
            case 0x0F:
                return 7;
            case 0x10:
                return 11;
            case 0x11:
                return 7;
            case 0x12:
                return 3;
            case 0x13:
                return 2;
            case 0x14:
                return 3;
            case 0x80:
                return 0;
            default:
                return 0;
        }
    }

    public void clear() {
        if (bluetoothGatt != null) {
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            bluetoothGatt = null;
        }
    }

    private void initControlInfoDialog() {
        // 传入 Application 对象表示设置成全局的
        show = new XToast(getActivity())
                .setView(R.layout.layout_show_control_point_dialog)
                .setDuration(0)
                // 设置动画样式
                .setAnimStyle(R.style.go_setting_anim_style)
                .setOnClickListener(R.id.btn_close_dialog, new com.hjq.xtoast.OnClickListener<Button>() {

                    @Override
                    public void onClick(XToast toast, Button view) {
                        // 点击这个 View 后消失
                        toast.cancel();
                        // 跳转到某个Activity
                        // toast.startActivity(intent);
                    }
                });
        ((TextView) (show.findViewById(R.id.tv_op_message))).setText(((DataTransmissionActivity)getActivity()).getScan_record());
        show.show();
    }

    public void recordLog(String log){
        Intent intent = new Intent();
        intent.setAction("send_log");
        DataLog dataLog = new DataLog(DateUtil.getCurrentTime(), " [record:] ", log , Color.parseColor("#FF4500"));
        intent.putExtra("ble_log", dataLog);
        getActivity().sendBroadcast(intent);
    }

}